<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2018/12/24
 * Time: 21:53
 */

namespace app\api\service;


use app\api\model\User;
use app\lib\Exception\TokenException;
use app\lib\power;
use think\Exception;

class UserToken extends Token
{
    public $code;
    public $wx_login;
    public $appID;
    public $wxSecret;

    public function __construct($code)
    {
        //获取常量

        $this->code = $code;
        $this->appID = config('wx.app_id');
        $this->wxSecret = config('wx.app_secret');
        $this->wx_login = sprintf(config('wx.wx_login'),
            $this->appID,$this->wxSecret,$this->code);
    }

    public function get()
    {

        //发送请求获取openID和session__KEY
        $result = curl_get($this->wx_login);
        //将受到的json请求转化为数字
        $wxResult = json_decode($result,true);

        //判断请求为空
        if(!$wxResult)
        {
            throw new Exception('获取openID,session_KEY异常，微信内部错误');
        }else{
            //这里是经验上的做法，就算请求不为空，那么，里面如果有error的键,依然是请求失败
            $loginFali = array_key_exists('errcode',$wxResult);
            if($loginFali) {
                //异常处理
                $this->PutsLoginError($wxResult);
            }else{
                //生成并返回TOKEN
                return $this->grantToken($wxResult);
            }
        }
    }

    //异常
    private function PutsLoginError($wxResult)
    {
        throw new TokenException([
            'message' => $wxResult['errcode'],
            'code' => 500,
            'error_code' => 10003
        ]);
    }

    private function grantToken($wxResult)
    {
        //openid 已经存在这个返回请求里了
        $openid = $wxResult['openid'];
        //去数据库里找一下这个openid是否存在
        $user = User::getByOpenID($openid);
        if(!$user) {
            //如果没有，那么就创建他
            $uid = $this->NewUser($openid);
        }else{
            //如果有，那么就使用他
            $uid = $user->id;
        }
        //这里在数组中写入用户和权限
        $checkdValue = $this->PrepareCheckDValue($wxResult,$uid);
        //将数组写入缓存
        $token = $this->saveToCheck($checkdValue);
        //终于 得到token了
        return $token;
    }

    //创建
    private function NewUser($openid)
    {
        //这个原来能实例化,学习到了
        $user = User::create([
            'openid' => $openid
        ]);

        return $user->id;
    }

    //将用户信息写入数组
    private function PrepareCheckDValue($wxResult,$uid)
    {
        $checkdValue = $wxResult;
        $checkdValue['uid'] = $uid;
        $checkdValue['chmod'] = power::Son;

        return $checkdValue;
    }

    //写入缓存
    private function saveToCheck($checkdValue)
    {
        //这里生成随机32位字符串
        $key = self::generateToken();
        //转化为字符串类型
        $value = json_encode($checkdValue);
        //获得token生存时间
        $time = config('wx.token_live_time');
        //写入缓存
        $result = cache($key,$value,$time);
        if(!$result)
        {
            throw new TokenException([
                'message' => '服务器缓存异常',
                'code' => 500,
                'code' => 10004
            ]);
        }

        //返回TOKEN
        return $key;
    }

}